#!/bin/bash

# ACLR: Advanced Command Line Ripper
# Copyright (C) 1998-2001 Robert Woodcock <rcw@debian.org>
# Copyright (C) 2003-2005 Jesus Climent <jesus.climent@hispalinux.es>
# Copyright (C) 2006-2007 Rob Frawley <code@robfrawley.net>
# Version $Id$

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

# version of program
VERSION="0.1.0"

# program information
display_program_info ()
{
	display_version_info
	echo ""
	echo "Copyright (C) 1998-2001 Robert Woodcock <rcw@debian.org>"
	echo "Copyright (C) 2003-2005 Jesus Climent <jesus.climent@hispalinux.es>"
	echo "Copyright (C) 2006-2007 Rob Frawley <robfrawley@stripslashes.net>"
	echo ""
	echo "This program comes with ABSOLUTELY NO WARRANTY. This is free"
	echo "software, and you are welcome to redistribute it under" 
	echo "certain conditions; type 'aclr -l' for additional details."
	echo ""
}

# version information
display_version_info ()
{
	echo "ACLR: Advanced Command Line Ripper (version $VERSION)"
}

# usage definitions
display_usage_info ()
{
	echo "Usage: aclr [options]"
	echo "Options:"
	echo "        -c <config_file_path>"
	echo "           Set the config file path"
	echo "        -h Display help information"
	echo "        -l Display license information"
	echo "        -v Display version information"
}

# full copyright file
display_copyright_info ()
{
	echo "Detailed copyright information can be found in the accompanying COPYING file."
}

# check for media in the cdrom drive
check_for_media ()
{
	execute "$PATH_CDPARANOIA --query --quiet" 1
	if [ "$?" -eq 0 ]; then
		return 0
	else
		return 1
	fi
}

# find a suitable cdrom drive
check_for_drive ()
{
	if [ "$CDROM" != "" ] ; then
		return
	fi
	if [ -e /dev/cdroms/cdrom0 ]; then
		CDROM=/dev/cdroms/cdrom0
	elif [ -e /dev/cdrom ]; then
		CDROM=/dev/cdrom
	elif [ -e /dev/cd0c ]; then
		CDROM=/dev/cd0c
	elif [ -e /dev/acd0c ]; then
		CDROM=/dev/acd0c
	elif [ -e /dev/disk1 ]; then
		CDROM=/dev/disk1
	fi
}

# include configuration files
check_for_configuration ()
{
	# load systemwide settings
	if [ -r /etc/aclr.conf ]; then
		. /etc/aclr.conf
	fi
	# load userland settings
	if [ -r $HOME/.aclr.conf ]; then
		. $HOME/.aclr.conf
	fi
}

send_notice ()
{
	if [ -z "$1" ]; then
		local notice="An unknown notice was sent."
	else
		local notice="$1"
	fi
	display_message "$notice" -1
}

send_warning ()
{
	if [ -z "$1" ]; then
		local warning="An unknown warning was sent."
	else
		local warning="$1"
	fi
	display_message "$warning" 0
}

send_error ()
{
	if [ -z "$1" ]; then
		local error="An unknown error was sent."
	else
		local error="$1"
	fi
	display_message "$error" 1
	exit 1
}

# handle message responsabilitied
display_message ()
{
	if [ "$2" == "-1" ]; then
		local level="-"
	elif [ "$2" == "0" ]; then
		local level="*"
	elif [ "$2" == "1" ]; then
		local level="!"
	else
		local level=" "
	fi
	if [ -z $3 ]; then
		local opts=""
	else
		local opts="$3 "
	fi
	local ts=`date "+%D %H:%M:%S"`
	echo "$opts[${ts}] $level $1"
}

# get the disk it using the diskid util
get_discid ()
{
	
	DISKID=$PATH_DISKID $CDROM
	echo $DISKID
	if [ ! "$?" -eq 0 ]; then
		send_error "Could not determine disk id.  Is there a CD in the drive?"
	fi
}

# check the status in the session status file
get_status ()
{
	if [ -z "$1" ]; then
		return 1
	fi
	PATTERN="^$1(=.*)?$"
	LASTLINE=$(egrep $PATTERN "${OUTPUT_SESSION_DIRECTORY}/status" | tail -n 1)
	if [ -z "$LASTLINE" ]; then
		return 1
	else
		return 0
	fi
}

# execute given command
execute ()
{
	# execute the given command and direct all stdout and stderr to null
	$1 >/dev/null 2>&1
	local return="$?"
	# write and display error
	if [ "$return" -ne 0 ]; then
		if [ -n "$2" ] && [ "$2" == "1" ]; then
			return $return
		else
			send_error "Execution failed for $1"
		fi
	fi
	return $return
}

# pre-read function
pre_read ()
{
:
}

# pre-extract function
pre_extract ()
{
:
}

# post-extract function
post_extract ()
{
:
}

# main script function
main ()
{
	# load system and user defined configuration files
	check_for_configuration
	# find location of the cdrom drive
	check_for_drive
	# handle command line options
	while getopts "c:hlv" o; do
		case "$o" in
			c )
				if [ -r $OPTARG ]; then
					. "$OPTARG"
				else
					send_error "Command line specified config file \"$OPTARG\" was not present or readable."
				fi
				;;
			h )
				display_usage_info
				exit 0
				;;
			l )
				display_copyright_info
				exit 0
				;;
			v )
				display_version_info
				exit 0
				;;
			\? )
				display_usage_info
				exit 1
				;;
			* )
				display_usage_info
				exit 1
				;;
		esac
	done
	# display program information
	display_program_info
	# check output directory
	if [ -z $OUTPUT_DIRECTORY ]; then
		OUTPUT_DIRECTORY=`pwd`/;
		send_notice "Setting output directory to $OUTPUT_DIRECTORY"
	fi
	# check temporary output directory
	if [ -z $OUTPUT_TMP_DIRECTORY ]; then
		OUTPUT_TMP_DIRECTORY=`pwd`/.tmp/
		send_notice "Setting temporary directory to $OUTPUT_TMP_DIRECTORY"
	fi
	# check all executables and create full commands using opts string
	for PROG in DISKID CDPARANOIA OGG FLAC HTTPGET
	do
		TMP="PATH_${PROG}"
		EXECUTABLE="${!TMP}"
		if [ "$(which $EXECUTABLE)" = "" ]; then
			send_error "$EXECUTABLE is not in your path"
		elif [ ! -x $(which $EXECUTABLE) ]; then
			send_error "$EXECUTABLE is not executable"
		fi
		TMP="OPTS_${PROG}"
		OPTS="${!TMP}"
		TMP="COMP_${PROG}"
		declare $TMP="$EXECUTABLE $OPTS"
	done
	# while look checking for cd in drive
	while true;
	do
		check_for_media
		if [ "$?" -ne 0 ]; then
			send_notice "No media present in drive $CDROM: sleeping $OPTS_SLEEP"
			execute "$PATH_SLEEP $OPTS_SLEEP"
			continue
		fi
		send_notice "Media present in drive $CDROM: starting extraction process"
		# execute user-defined pre-read function
		pre_read
		# retrieve disc id
		get_discid
		# determine session temporary directory
		OUTPUT_SESSION_DIRECTORY="${OUTPUT_TMP_DIRECTORY}aclr.$(echo $DISKID | cut -f1 -d' ')"
		echo "THIS IS COOL $OUTPUT_SESSION_DIRECTORY"
		# check for temporary directory existance
		if [ ! -d $OUTPUT_TMP_DIRECTORY ]; then
			mkdir "${OUTPUT_TMP_DIRECTORY}"
			if [ "$?" -gt "0" ]; then
				send_error "Could not create temporary directory ${OUTPUT_TMP_DIRECTORY}."
			fi
		fi
		# check for session temporary directory existance
		if [ -e "$OUTPUT_SESSION_DIRECTORY" ]; then
			# check if it is not a directory
			if [ ! -d "${OUTPUT_SESSION_DIRECTORY}" ]; then
				send_error "Session temporary directory ${OUTPUT_SESSION_DIRECTORY} is not a directory!  Please remove it and restart the program."
			fi
			# check to see if the current user owns the directory
			if [ ! -O "${OUTPUT_SESSION_DIRECTORY}" ]; then
				WHO=`whoami`
				send_error "Session temporary directory ${OUTPUT_SESSION_DIRECTORY} is not owned by the current user ${WHO}!  Please remove it and restart the program."
			fi
			else
			# directory does not exists and must be created
			mkdir "$OUTPUT_SESSION_DIRECTORY"
			# check for success
			if [ "$?" -gt "0" ]; then
				send_error "Could not create session temporary directory ${OUTPUT_SESSION_DIRECTORY}"
			fi
		fi
		# write the diskid to a file
		echo "$DISKID" > "${OUTPUT_SESSION_DIRECTORY}/discid"
		# write blank status file
		touch "${OUTPUT_SESSION_DIRECTORY}/status"
	done
	# exit successfully
	exit 0
}

# sleep executable
PATH_SLEEP="sleep"

# sleep opts
OPTS_SLEEP="2s"

# cd-diskid executable path
PATH_DISKID="cd-discid"

# cdparanoia executable path
PATH_CDPARANOIA="cdparanoia"

# cdparanoia opts
OPTS_CDPARANOIA=""

# ogg encoder path
PATH_OGG="oggenc"

# ogg opts
OPTS_OGG=""

# flac encoder path
PATH_FLAC="flac"

# flac opts
OPTS_FLAC=""

# mp3 encoder path
PATH_MP3="mp3enc"

# mp3 opts
OPTS_MP3=""

# http path
PATH_HTTPGET="wget"

# http opts
OPTS_HTTPGET="-q -O -"

# cddb url
CDDB_URL="http://freedb.freedb.org/~cddb/cddb.cgi"

# cddb submission address
CDDB_SUBMIT_ADDRESS="freedb-submit@freedb.org"

# cddb submit user address
CDDB_SUBMIT_INFO="$(whoami)@$(hostname)"

# output format
OUTPUT_FORMAT='${ARTISTFILE}-${ALBUMFILE}/${TRACKNUM}.${TRACKFILE}'

# execute main script function
main $@